package storm;

import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;

import twitter4j.FilterQuery;
import twitter4j.StallWarning;
import twitter4j.Status;
import twitter4j.StatusDeletionNotice;
import twitter4j.StatusListener;
import twitter4j.TwitterStream;
import twitter4j.TwitterStreamFactory;
import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values;

public class TwitterSpout extends BaseRichSpout implements StatusListener {

	private static final long serialVersionUID = -1208286091839870282L;
	private LinkedBlockingQueue<Status> queue;
	private SpoutOutputCollector collector;
	private TwitterStream twitterStream;

	/* Spout methods */

	@Override
	public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
		this.collector = collector;
		queue = new LinkedBlockingQueue<Status>();
		twitterStream = new TwitterStreamFactory().getInstance();
		twitterStream.addListener(this);
		FilterQuery query = new FilterQuery();
		String[] lang = {"en"};
		query.language(lang);
		//String[] track = new String[] {"#android"};
		//String[] track = new String[] {"#jobs"};
		//String[] track = new String[] {"#love"};
		//String[] track = new String[] {"#ipad"};
		String[] track = new String[] {"#iphone"};
		query.track(track);
		twitterStream.filter(query);
	}

	@Override
	public void nextTuple() {
		Status s;
		try {
			s = queue.take();
			collector.emit(new Values(s));
		} catch (InterruptedException e) {	}
	}

	@Override
	public void declareOutputFields(OutputFieldsDeclarer declarer) {
		declarer.declare(new Fields("tweet"));
	}
	
	@Override
	public void close() {
		twitterStream.cleanUp();
		super.close();
	}
	
	/* StatusListener Methods */

	@Override
	public void onException(Exception arg0) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onDeletionNotice(StatusDeletionNotice arg0) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onScrubGeo(long arg0, long arg1) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onStallWarning(StallWarning arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStatus(Status status) {
		try {
			queue.put(status);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onTrackLimitationNotice(int arg0) {
		// TODO Auto-generated method stub
	}

}
